﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Collections;

namespace CoolERP_Web
{
    public interface ICacheManager
    {
        /// <summary>
        /// 添加指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="obj">缓存对象</param>
        void Add(string key, object obj);

        /// <summary>
        /// 添加指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="obj">缓存对象</param>
        /// <param name="expire">到期时间,单位:秒</param>
        void Add(string key, object obj, int expire);

        /// <summary>
        /// 加入当前对象到缓存中,并使用依赖键
        /// </summary>
        /// <param name="key">对象的键值</param>
        /// <param name="obj">缓存的对象</param>
        /// <param name="dependKey">依赖关联的键值</param>
        void AddWithDepend(string key, object obj, string[] dependKey);

        /// <summary>
        /// 加入当前对象到缓存中,并使用依赖键
        /// </summary>
        /// <param name="key">对象的键值</param>
        /// <param name="obj">缓存的对象</param>
        /// <param name="expire">到期时间,单位:秒</param>
        /// <param name="dependKey">依赖关联的键值</param>
        void AddWithDepend(string key, object obj, int expire, string[] dependKey);

        /// <summary>
        /// 返回指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        object Get(string key);

        /// <summary>
        /// 更新指定的缓存对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        void Set(string key, object obj);

        /// <summary>
        /// 是否存在key
        /// </summary>
        /// <param name="key">键</param>
        bool Exist(string key);

        /// <summary>
        /// 移除指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        void Remove(string key);

        /// <summary>
        /// 清空所有缓存数据
        /// </summary>
        void Clear();

        /// <summary>
        /// 到期时间,单位：秒
        /// </summary>
        int TimeOut { set; get; }
    }

    public class CacheManager : ICacheManager
    {
        protected static volatile System.Web.Caching.Cache webCache = HttpRuntime.Cache;
        /// <summary>
        /// 默认缓存存活期为3600秒(1小时)
        /// </summary>
        protected int _timeOut = 3600;
        /// <summary>
        /// 设置缓存到期相对时间[单位: 秒] 
        /// </summary>
        public virtual int TimeOut
        {
            get { return _timeOut; }
            set { _timeOut = value; }
        }

        public CacheManager()
        {
        }

        #region ICacheManager 成员

        /// <summary>
        /// 添加指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="obj">缓存对象</param>
        public virtual void Add(string key, object obj)
        {
            if (string.IsNullOrEmpty(key) || obj == null)
                return;
            this.Add(key, obj, TimeOut);
        }

        /// <summary>
        /// 添加指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="obj">缓存对象</param>
        /// <param name="expire">到期时间,单位:秒</param>
        public void Add(string key, object obj, int expire)
        {
            if (string.IsNullOrEmpty(key) || obj == null)
                return;
            this.TimeOut = expire;
            //0表示永不过期
            if (TimeOut == 0)
                webCache.Insert(key, obj, null, DateTime.MaxValue, TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);
            else
                webCache.Insert(key, obj, null, DateTime.Now.AddSeconds(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, null);
        }

        /// <summary>
        /// 加入当前对象到缓存中,并使用依赖键
        /// </summary>
        /// <param name="key">对象的键值</param>
        /// <param name="obj">缓存的对象</param>
        /// <param name="dependKey">依赖关联的键值</param>
        public void AddWithDepend(string key, object obj, string[] dependKey)
        {
            if (string.IsNullOrEmpty(key) || obj == null)
                return;
            this.AddWithDepend(key, obj, 0, dependKey);
        }

        /// <summary>
        /// 加入当前对象到缓存中,并使用依赖键
        /// </summary>
        /// <param name="key">对象的键值</param>
        /// <param name="obj">缓存的对象</param>
        /// <param name="expire">到期时间,单位:秒</param>
        /// <param name="dependKey">依赖关联的键值</param>
        public void AddWithDepend(string key, object obj, int expire, string[] dependKey)
        {
            if (string.IsNullOrEmpty(key) || obj == null)
                return;
            CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);
            CacheDependency dep = new CacheDependency(null, dependKey, DateTime.Now);
            if (expire > 0)
                this.TimeOut = expire;

            webCache.Insert(key, obj, dep, System.DateTime.Now.AddSeconds(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
        }

        /// <summary>
        /// 建立回调委托的一个实例
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <param name="reason"></param>
        public void onRemove(string key, object obj, CacheItemRemovedReason reason)
        {
            switch (reason)
            {
                case CacheItemRemovedReason.DependencyChanged:
                    break;
                case CacheItemRemovedReason.Expired:
                    {
                        //CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(this.onRemove);
                        //webCache.Insert(key, obj, null, System.DateTime.Now.AddMinutes(TimeOut),
                        //    System.Web.Caching.Cache.NoSlidingExpiration,
                        //    System.Web.Caching.CacheItemPriority.High,
                        //    callBack);
                        break;
                    }
                case CacheItemRemovedReason.Removed:
                    break;
                case CacheItemRemovedReason.Underused:
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 返回指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        public object Get(string key)
        {
            if (string.IsNullOrEmpty(key)) return null;
            return webCache.Get(key);
        }

        /// <summary>
        /// 更新指定的缓存对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        public void Set(string key, object obj)
        {
            webCache[key] = obj;
        }

        /// <summary>
        /// 是否存在key
        /// </summary>
        /// <param name="key">键</param>
        public bool Exist(string key)
        {
            return webCache.Get(key) != null;
        }

        /// <summary>
        /// 移除指定key的对象
        /// </summary>
        /// <param name="key">缓存键</param>
        public void Remove(string key)
        {
            if (string.IsNullOrEmpty(key)) return;
            webCache.Remove(key);
        }

        /// <summary>
        /// 清空所有缓存数据
        /// </summary>
        public void Clear()
        {
            IDictionaryEnumerator CacheEnum = HttpRuntime.Cache.GetEnumerator();
            while (CacheEnum.MoveNext())
            {
                webCache.Remove(CacheEnum.Key.ToString());
            }
        }
        #endregion
    }
}